package com.dusk.tool
{
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.display.DisplayObject;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	public class HitTest
	{
		/**
		 * 将显示对象使用bitmap重绘后再进行碰撞检测，可以有效防止遮罩元件实际范围比显示范围大的问题
		 * @param obj1 显示对象1
		 * @param obj2 显示对象2
		 * @param scale 缩放倍率
		 * @return 是否碰撞
		 */
		public static function complexHitTestObject(obj1:DisplayObject, obj2:DisplayObject, scale:Number = 1):Boolean
		{
			if (scale > 1)
			{
				scale = 1;
			}
			return scale <= 0 ? false : complexIntersectionRectangle(obj1, obj2, scale).width != 0;
		}
		
		private static function intersectionRectangle(obj1:DisplayObject, obj2:DisplayObject):Rectangle
		{
			if (!obj1.root || !obj2.root || !obj1.hitTestObject(obj2))
			{
				return new Rectangle();
			}
			var rect1:Rectangle = obj1.getBounds(obj1.root);
			var rect2:Rectangle = obj2.getBounds(obj2.root);
			var rect3:Rectangle = new Rectangle();
			rect3.x = Math.max(rect1.x, rect2.x);
			rect3.y = Math.max(rect1.y, rect2.y);
			rect3.width = Math.min(rect1.x + rect1.width - rect3.x, rect2.x + rect2.width - rect3.x);
			rect3.height = Math.min(rect1.y + rect1.height - rect3.y, rect2.y + rect2.height - rect3.y);
			return rect3;
		}
		
		/**
		 * 计算两个显示对象之间的复杂相交情况下的矩形相交区域
		 * @param obj1 显示对象1
		 * @param obj2 显示对象2
		 * @param accuracy 精度，默认为1
		 * @return 返回相交区域的矩形，如果没有相交则返回一个空的矩形
		 */
		private static function complexIntersectionRectangle(obj1:DisplayObject, obj2:DisplayObject, accuracy:Number = 1):Rectangle
		{
			if (accuracy <= 0)
			{
				throw new Error("ArgumentError: Error #5001: Invalid value for accuracy");
			}
			if (!obj1.hitTestObject(obj2))
			{
				return new Rectangle();
			}
			var _loc4_:Rectangle = intersectionRectangle(obj1, obj2);
			if (_loc4_.width * accuracy < 1 || _loc4_.height * accuracy < 1)
			{
				return new Rectangle();
			}
			var _loc5_:BitmapData = new BitmapData(_loc4_.width * accuracy, _loc4_.height * accuracy, false, 0);
			_loc5_.draw(obj1, HitTest.getDrawMatrix(obj1, _loc4_, accuracy), new ColorTransform(1, 1, 1, 1, 255, -255, -255, 255));
			_loc5_.draw(obj2, HitTest.getDrawMatrix(obj2, _loc4_, accuracy), new ColorTransform(1, 1, 1, 1, 255, 255, 255, 255), BlendMode.DIFFERENCE);
			var _loc6_:Rectangle = _loc5_.getColorBoundsRect(0xFFFFFFFF, 0xFF00FFFF);
			_loc5_.dispose();
			if (accuracy != 1)
			{
				_loc6_.x /= accuracy;
				_loc6_.y /= accuracy;
				_loc6_.width /= accuracy;
				_loc6_.height /= accuracy;
			}
			_loc6_.x += _loc4_.x;
			_loc6_.y += _loc4_.y;
			return _loc6_;
		}
		
		private static function getDrawMatrix(param1:DisplayObject, param2:Rectangle, param3:Number):Matrix
		{
			var _loc6_:Matrix = param1.root.transform.concatenatedMatrix;
			var _loc4_:Point = param1.localToGlobal(new Point());
			var _loc5_:Matrix = param1.transform.concatenatedMatrix;
			_loc5_.tx = _loc4_.x - param2.x;
			_loc5_.ty = _loc4_.y - param2.y;
			_loc5_.a /= _loc6_.a;
			_loc5_.d /= _loc6_.d;
			if (param3 != 1)
			{
				_loc5_.scale(param3, param3);
			}
			return _loc5_;
		}
	}
}
